#ifndef _E2K_CACHE_H_
#define _E2K_CACHE_H_

/* E3M caches parameters */
#define	E3M_L1_CACHE_SIZE	64	/* Kbytes */
#define E3M_L1_CACHE_SHIFT	5
#define E3M_L1_CACHE_BYTES	(1 << E3M_L1_CACHE_SHIFT)
#define	E3M_L2_CACHE_SIZE	256	/* Kbytes */
#define E3M_L2_CACHE_SHIFT	6
#define E3M_L2_CACHE_BYTES	(1 << E3M_L2_CACHE_SHIFT)

/* Simulator of E3M caches parameters */
#define	E3M_LMS_L1_CACHE_SIZE	0	/* LMS does not support any caches */
#define E3M_LMS_L1_CACHE_SHIFT	3	/* double-word */
#define E3M_LMS_L1_CACHE_BYTES	(1 << E3M_L1_CACHE_SHIFT)
#define	E3M_LMS_L2_CACHE_SIZE	0	/* Kbytes */
#define E3M_LMS_L2_CACHE_SHIFT	0
#define E3M_LMS_L2_CACHE_BYTES	(1 << E3M_L2_CACHE_SHIFT)

/* E3S caches parameters */
#define	E3S_L1_CACHE_SIZE	64	/* Kbytes */
#define E3S_L1_CACHE_SHIFT	5
#define E3S_L1_CACHE_BYTES	(1 << E3M_L1_CACHE_SHIFT)
#define	E3S_L2_CACHE_SIZE	2048	/* Kbytes */
#define E3S_L2_CACHE_SHIFT	6
#define E3S_L2_CACHE_BYTES	(1 << E3M_L2_CACHE_SHIFT)

/* Simulator of E3S caches parameters */
#define	E3S_LMS_L1_CACHE_SIZE	0	/* LMS does not support any caches */
#define E3S_LMS_L1_CACHE_SHIFT	3	/* doudle-word */
#define E3S_LMS_L1_CACHE_BYTES	(1 << E3S_LMS_L1_CACHE_SHIFT)
#define	E3S_LMS_L2_CACHE_SIZE	0	/* Kbytes */
#define E3S_LMS_L2_CACHE_SHIFT	0
#define E3S_LMS_L2_CACHE_BYTES	(1 << E3S_LMS_L2_CACHE_SHIFT)

/* ES2 caches parameters */
#define	ES2_L1_CACHE_SIZE	E3S_L1_CACHE_SIZE
#define ES2_L1_CACHE_SHIFT	E3S_L1_CACHE_SHIFT
#define ES2_L1_CACHE_BYTES	E3S_L1_CACHE_BYTES
#define	ES2_L2_CACHE_SIZE	(E3S_L2_CACHE_SIZE / 2)	/* 1024 Kbytes */
#define ES2_L2_CACHE_SHIFT	E3S_L2_CACHE_SHIFT
#define ES2_L2_CACHE_BYTES	E3S_L2_CACHE_BYTES

/* Simulator of ES2 caches parameters */
#define	ES2_LMS_L1_CACHE_SIZE	E3S_LMS_L1_CACHE_SIZE
#define ES2_LMS_L1_CACHE_SHIFT	E3S_LMS_L1_CACHE_SHIFT
#define ES2_LMS_L1_CACHE_BYTES	E3S_LMS_L1_CACHE_BYTES
#define	ES2_LMS_L2_CACHE_SIZE	E3S_LMS_L2_CACHE_SIZE
#define ES2_LMS_L2_CACHE_SHIFT	E3S_LMS_L2_CACHE_SHIFT
#define ES2_LMS_L2_CACHE_BYTES	E3S_LMS_L2_CACHE_BYTES

/* E2S caches parameters */
#define	E2S_L1_CACHE_SIZE	E3S_L1_CACHE_SIZE
#define E2S_L1_CACHE_SHIFT	E3S_L1_CACHE_SHIFT
#define E2S_L1_CACHE_BYTES	E3S_L1_CACHE_BYTES
#define	E2S_L2_CACHE_SIZE	E3S_L2_CACHE_SIZE
#define E2S_L2_CACHE_SHIFT	E3S_L2_CACHE_SHIFT
#define E2S_L2_CACHE_BYTES	E3S_L2_CACHE_BYTES

/* Simulator of ES2 caches parameters */
#define	E2S_LMS_L1_CACHE_SIZE	E3S_LMS_L1_CACHE_SIZE
#define E2S_LMS_L1_CACHE_SHIFT	E3S_LMS_L1_CACHE_SHIFT
#define E2S_LMS_L1_CACHE_BYTES	E3S_LMS_L1_CACHE_BYTES
#define	E2S_LMS_L2_CACHE_SIZE	E3S_LMS_L2_CACHE_SIZE
#define E2S_LMS_L2_CACHE_SHIFT	E3S_LMS_L2_CACHE_SHIFT
#define E2S_LMS_L2_CACHE_BYTES	E3S_LMS_L2_CACHE_BYTES

/* E8C caches parameters */
#define	E8C_L1_CACHE_SIZE	E3S_L1_CACHE_SIZE
#define E8C_L1_CACHE_SHIFT	E3S_L1_CACHE_SHIFT
#define E8C_L1_CACHE_BYTES	E3S_L1_CACHE_BYTES
#define	E8C_L2_CACHE_SIZE	(E3S_L2_CACHE_SIZE / 4)	/* 512 Kbytes */
#define E8C_L2_CACHE_SHIFT	E3S_L2_CACHE_SHIFT
#define E8C_L2_CACHE_BYTES	E3S_L2_CACHE_BYTES
#define	E8C_L3_CACHE_SIZE	(16 * 1024)		/* 16 Mbytes */
#define E8C_L3_CACHE_SHIFT	6
#define E8C_L3_CACHE_BYTES	(1 << E8C_L3_CACHE_SHIFT)

/* Simulator of E8C caches parameters */
#define	E8C_LMS_L1_CACHE_SIZE	E3S_LMS_L1_CACHE_SIZE
#define E8C_LMS_L1_CACHE_SHIFT	E3S_LMS_L1_CACHE_SHIFT
#define E8C_LMS_L1_CACHE_BYTES	E3S_LMS_L1_CACHE_BYTES
#define	E8C_LMS_L2_CACHE_SIZE	E3S_LMS_L2_CACHE_SIZE
#define E8C_LMS_L2_CACHE_SHIFT	E3S_LMS_L2_CACHE_SHIFT
#define E8C_LMS_L2_CACHE_BYTES	E3S_LMS_L2_CACHE_BYTES
#define	E8C_LMS_L3_CACHE_SIZE	0
#define E8C_LMS_L3_CACHE_SHIFT	0
#define E8C_LMS_L3_CACHE_BYTES	0

/* E1C+ caches parameters same as e2s  */
#define	E1CP_L1_CACHE_SIZE	E2S_L1_CACHE_SIZE
#define E1CP_L1_CACHE_SHIFT	E2S_L1_CACHE_SHIFT
#define E1CP_L1_CACHE_BYTES	E2S_L1_CACHE_BYTES
#define	E1CP_L2_CACHE_SIZE	E2S_L2_CACHE_SIZE
#define E1CP_L2_CACHE_SHIFT	E2S_L2_CACHE_SHIFT
#define E1CP_L2_CACHE_BYTES	E2S_L2_CACHE_BYTES

/* Simulator of E1C+ caches parameters */
#define	E1CP_LMS_L1_CACHE_SIZE	E2S_LMS_L1_CACHE_SIZE
#define E1CP_LMS_L1_CACHE_SHIFT	E2S_LMS_L1_CACHE_SHIFT
#define E1CP_LMS_L1_CACHE_BYTES	E2S_LMS_L1_CACHE_BYTES
#define	E1CP_LMS_L2_CACHE_SIZE	E2S_LMS_L2_CACHE_SIZE
#define E1CP_LMS_L2_CACHE_SHIFT	E2S_LMS_L2_CACHE_SHIFT
#define E1CP_LMS_L2_CACHE_BYTES	E2S_LMS_L2_CACHE_BYTES

/* E8C2 caches parameters */
#define	E8C2_L1_CACHE_SIZE	E3S_L1_CACHE_SIZE
#define E8C2_L1_CACHE_SHIFT	E3S_L1_CACHE_SHIFT
#define E8C2_L1_CACHE_BYTES	E3S_L1_CACHE_BYTES
#define	E8C2_L2_CACHE_SIZE	(E3S_L2_CACHE_SIZE / 4)	/* 512 Kbytes */
#define E8C2_L2_CACHE_SHIFT	E3S_L2_CACHE_SHIFT
#define E8C2_L2_CACHE_BYTES	E3S_L2_CACHE_BYTES
#define	E8C2_L3_CACHE_SIZE	E8C_L3_CACHE_SIZE	/* 16 Mbytes */
#define E8C2_L3_CACHE_SHIFT	E8C_L3_CACHE_SHIFT
#define E8C2_L3_CACHE_BYTES	E8C_L3_CACHE_BYTES

/* Simulator of E8C2 caches parameters */
#define	E8C2_LMS_L1_CACHE_SIZE	E3S_LMS_L1_CACHE_SIZE
#define E8C2_LMS_L1_CACHE_SHIFT	E3S_LMS_L1_CACHE_SHIFT
#define E8C2_LMS_L1_CACHE_BYTES	E3S_LMS_L1_CACHE_BYTES
#define	E8C2_LMS_L2_CACHE_SIZE	E3S_LMS_L2_CACHE_SIZE
#define E8C2_LMS_L2_CACHE_SHIFT	E3S_LMS_L2_CACHE_SHIFT
#define E8C2_LMS_L2_CACHE_BYTES	E3S_LMS_L2_CACHE_BYTES
#define	E8C2_LMS_L3_CACHE_SIZE	E8C_LMS_L3_CACHE_SIZE
#define E8C2_LMS_L3_CACHE_SHIFT	E8C_LMS_L3_CACHE_SHIFT
#define E8C2_LMS_L3_CACHE_BYTES	E8C_LMS_L3_CACHE_BYTES

/*
 * L1 cache data
 */
#define _max_(a, b)		((a) > (b) ? (a) : (b))
#ifdef	CONFIG_E2K_MACHINE
# if defined(CONFIG_E2K_E3M)
#  define	L1_CACHE_SHIFT		E3M_L1_CACHE_SHIFT
#  define	L2_CACHE_SHIFT		E3M_L2_CACHE_SHIFT
# elif defined(CONFIG_E2K_E3M_SIM)
#  define	L1_CACHE_SHIFT		E3M_LMS_L1_CACHE_SHIFT
#  define	L2_CACHE_SHIFT		E3M_LMS_L2_CACHE_SHIFT
# elif defined(CONFIG_E2K_E3M_IOHUB)
#  define	L1_CACHE_SHIFT		E3M_L1_CACHE_SHIFT
#  define	L2_CACHE_SHIFT		E3M_L2_CACHE_SHIFT
# elif defined(CONFIG_E2K_E3M_IOHUB_SIM)
#  define	L1_CACHE_SHIFT		E3M_LMS_L1_CACHE_SHIFT
#  define	L2_CACHE_SHIFT		E3M_LMS_L2_CACHE_SHIFT
# elif defined(CONFIG_E2K_E3S)
#  define	L1_CACHE_SHIFT		E3S_L1_CACHE_SHIFT
#  define	L2_CACHE_SHIFT		E3S_L2_CACHE_SHIFT
# elif defined(CONFIG_E2K_E3S_SIM)
#  define	L1_CACHE_SHIFT		E3S_LMS_L1_CACHE_SHIFT
#  define	L2_CACHE_SHIFT		E3S_LMS_L2_CACHE_SHIFT
# elif defined(CONFIG_E2K_ES2_DSP) || defined(CONFIG_E2K_ES2_RU)
#  define	L1_CACHE_SHIFT		ES2_L1_CACHE_SHIFT
#  define	L2_CACHE_SHIFT		ES2_L2_CACHE_SHIFT
# elif defined(CONFIG_E2K_ES2_DSP_SIM) || defined(CONFIG_E2K_ES2_RU_SIM)
#  define	L1_CACHE_SHIFT		ES2_LMS_L1_CACHE_SHIFT
#  define	L2_CACHE_SHIFT		ES2_LMS_L2_CACHE_SHIFT
# elif defined(CONFIG_E2K_E2S)
#  define	L1_CACHE_SHIFT		E2S_L1_CACHE_SHIFT
#  define	L2_CACHE_SHIFT		E2S_L2_CACHE_SHIFT
# elif defined(CONFIG_E2K_E2S_SIM)
#  define	L1_CACHE_SHIFT		E2S_LMS_L1_CACHE_SHIFT
#  define	L2_CACHE_SHIFT		E2S_LMS_L2_CACHE_SHIFT
# elif defined(CONFIG_E2K_E8C)
#  define	L1_CACHE_SHIFT		E8C_L1_CACHE_SHIFT
#  define	L2_CACHE_SHIFT		E8C_L2_CACHE_SHIFT
#  define	L3_CACHE_SHIFT		E8C_L3_CACHE_SHIFT
# elif defined(CONFIG_E2K_E8C_SIM)
#  define	L1_CACHE_SHIFT		E8C_LMS_L1_CACHE_SHIFT
#  define	L2_CACHE_SHIFT		E8C_LMS_L2_CACHE_SHIFT
#  define	L3_CACHE_SHIFT		E8C_LMS_L3_CACHE_SHIFT
# elif defined(CONFIG_E2K_E1CP)
#  define	L1_CACHE_SHIFT		E1CP_L1_CACHE_SHIFT
#  define	L2_CACHE_SHIFT		E1CP_L2_CACHE_SHIFT
# elif defined(CONFIG_E2K_E1CP_SIM)
#  define	L1_CACHE_SHIFT		E1CP_LMS_L1_CACHE_SHIFT
#  define	L2_CACHE_SHIFT		E1CP_LMS_L2_CACHE_SHIFT
# elif defined(CONFIG_E2K_E8C2)
#  define	L1_CACHE_SHIFT		E8C2_L1_CACHE_SHIFT
#  define	L2_CACHE_SHIFT		E8C2_L2_CACHE_SHIFT
#  define	L3_CACHE_SHIFT		E8C2_L3_CACHE_SHIFT
# elif defined(CONFIG_E2K_E8C2_SIM)
#  define	L1_CACHE_SHIFT		E8C2_LMS_L1_CACHE_SHIFT
#  define	L2_CACHE_SHIFT		E8C2_LMS_L2_CACHE_SHIFT
#  define	L3_CACHE_SHIFT		E8C2_LMS_L3_CACHE_SHIFT
# else
#    error "E2K MACHINE type does not defined"
# endif
#else	/* ! CONFIG_E2K_MACHINE */
# define L1_CACHE_SHIFT_MAX						\
	_max_(_max_(_max_(_max_(_max_(_max_(E8C2_L1_CACHE_SHIFT,	\
					   E1CP_L1_CACHE_SHIFT),	\
				     E8C_L1_CACHE_SHIFT),		\
			       E2S_L1_CACHE_SHIFT),			\
			 ES2_L1_CACHE_SHIFT),				\
		   E3S_L1_CACHE_SHIFT),					\
	     E3M_L1_CACHE_SHIFT)
# define L2_CACHE_SHIFT_MAX						\
	_max_(_max_(_max_(_max_(_max_(_max_(E8C2_L2_CACHE_SHIFT,	\
					   E1CP_L2_CACHE_SHIFT),	\
				     E8C_L2_CACHE_SHIFT),		\
			       E2S_L2_CACHE_SHIFT),			\
			 ES2_L2_CACHE_SHIFT),				\
		   E3S_L2_CACHE_SHIFT),					\
	     E3M_L2_CACHE_SHIFT)
# define L3_CACHE_SHIFT_MAX	_max_(E8C_L3_CACHE_SHIFT, E8C2_L3_CACHE_SHIFT)

# define L1_CACHE_SHIFT		L1_CACHE_SHIFT_MAX
# define L2_CACHE_SHIFT		L2_CACHE_SHIFT_MAX
# define L3_CACHE_SHIFT		L3_CACHE_SHIFT_MAX
#endif /* CONFIG_E2K_MACHINE */

#define	L1_CACHE_BYTES		(1 << L1_CACHE_SHIFT)
#define	L2_CACHE_BYTES		(1 << L2_CACHE_SHIFT)
#define	L3_CACHE_BYTES		(1 << L3_CACHE_SHIFT)

/* Stores pass through L1$, so we should use the biggest size. */
#define	SMP_CACHE_BYTES		_max_(L1_CACHE_BYTES, L2_CACHE_BYTES)
#define INTERNODE_CACHE_SHIFT	_max_(L1_CACHE_SHIFT, L2_CACHE_SHIFT)

#define INTERNODE_CACHE_BYTES	(1 << INTERNODE_CACHE_SHIFT)

#define __read_mostly __attribute__((__section__(".data..read_mostly")))

#endif /* _E2K_CACHE_H_ */
